#include "unity.h"
#include "user_repository.h"
#include "session_repository.h"
#include "auth_service.h"
#include "database_manager.h"
#include <iostream>
#include "user.h"

// Global pointers for testing - will be initialized in setUp
static DatabaseManager* dbManager = nullptr;
static UserRepository* userRepository = nullptr;
static SessionRepository* sessionRepository = nullptr;
static AuthService* authService = nullptr;

// Global variables to track test results
static bool login_success = false;
static bool login_failure = false;

// Event handlers
static void onLoginSuccess() {
    login_success = true;
}

static void onLoginFailure() {
    login_failure = true;
}

void setUp(void)
{
    // This is run before EACH test
    // Create a unique database file for this test
    static int test_counter = 0;
    std::string db_path = "data/test_auth_user_not_found_" + std::to_string(++test_counter) + ".db";
    
    // Create data directory if it doesn't exist
    system("mkdir -p data");
    
    // Initialize database manager with unique database file
    dbManager = new DatabaseManager(db_path);
    userRepository = new UserRepository(dbManager->getDatabaseConnection());
    sessionRepository = new SessionRepository(dbManager->getDatabaseConnection());
    authService = new AuthService(*userRepository, *sessionRepository);
    
    // Initialize database
    dbManager->initialize();
    
    // Reset test result flags
    login_success = false;
    login_failure = false;
    
    // Register event listeners
    authService->getEventDispatcher().appendListener("AUTH_LOGIN_RESPONSE_SUCCESS", onLoginSuccess);
    authService->getEventDispatcher().appendListener("AUTH_LOGIN_RESPONSE_FAILURE", onLoginFailure);
    
    std::cout << "Test environment initialized" << std::endl;
}

void tearDown(void)
{
    // This is run after EACH test
    // Clean up allocated memory
    delete authService;
    delete sessionRepository;
    delete userRepository;
    delete dbManager;
    
    // Remove the test database file
    system("rm -f data/test_auth_user_not_found_*.db");
}

// Test that authenticating with non-existent username returns failure
void test_auth_user_not_found(void)
{
    // Test login with non-existent user
    authService->onLoginRequest("nonexistent", "password");
    
    // Verify that login failed event was dispatched
    TEST_ASSERT_FALSE(login_success);
    TEST_ASSERT_TRUE(login_failure);
}

int main(void)
{
    UNITY_BEGIN();
    RUN_TEST(test_auth_user_not_found);
    return UNITY_END();
}